package com.example.josan.greendaodemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;

import org.greenrobot.greendao.query.Query;

import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private final static String DB_NAME = "student.db";

    @BindView(R.id.tv_add)
    TextView tvAdd;
    @BindView(R.id.tv_delete)
    TextView tvDelete;
    @BindView(R.id.tv_update)
    TextView tvUpdate;
    @BindView(R.id.tv_select)
    TextView tvSelect;
    @BindView(R.id.tv_result)
    TextView tvResult;

    DaoSession daoSession;
    StudentMsgBean studentMsgBean;
    StudentMsgBeanDao msgBeanDao;
    ScoreBeanDao scoreBeanDao;
    @BindView(R.id.tv_multie_select)
    TextView tvMultieSelect;
    @BindView(R.id.tv_one_to_one)
    TextView tvOneToOne;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        initGreenDao();
    }

    private void initGreenDao() {
        DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(getApplicationContext(), DB_NAME);
        DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDb());
        daoSession = daoMaster.newSession();
        msgBeanDao = daoSession.getStudentMsgBeanDao();
        scoreBeanDao = daoSession.getScoreBeanDao();
    }

    /**
     * 增
     * 如果实体类有更新，那么要调用daoSession.clear()清除缓存，才能得到更新
     * 如果实体类的属性被unique注解，则传入的时候，不能插入两条该字段重复的记录，否则会报下面的错误
     * UNIQUE constraint failed: STUDENT_MSG_BEAN.NAME
     */
    @OnClick(R.id.tv_add)
    public void onTvAddClicked() {
        studentMsgBean = new StudentMsgBean();
        studentMsgBean.setName("josan24");
        studentMsgBean.setStudentNum("24");
        // 当出入这个实体bean以后，id就已经被赋值了，所以不能再次修改该实体类再插入，因为id相同了
        // 如果要插入，需要重新创建实体对象（修改当前实体id插入能成功，但是第二条记录会update第一条记录）
        msgBeanDao.insert(studentMsgBean);

        StudentMsgBean studentMsgBean1 = new StudentMsgBean();
        studentMsgBean1.setName("josan25");
        studentMsgBean1.setStudentNum("24");
        msgBeanDao.insert(studentMsgBean1);
    }

    /**
     * 删除
     * 删除可以根据实体类、主键、删除所有
     */
    @OnClick(R.id.tv_delete)
    public void onTvDeleteClicked() {
        List<StudentMsgBean> list = msgBeanDao.queryBuilder().build().list();
        // 根据实体类，删除第一个数据
        msgBeanDao.delete(list.get(0));
        // 根据ID来删除第3条数据
        msgBeanDao.deleteByKey(list.get(2).getId());
        // 删除所有的数据
        msgBeanDao.deleteAll();
    }

    /**
     * 进行修改
     * update一个不存在的实体类对象，不会有任何效果，不会自动插入
     */
    @OnClick(R.id.tv_update)
    public void onTvUpdateClicked() {
        List<StudentMsgBean> list = msgBeanDao.queryBuilder().build().list();
        StudentMsgBean studentMsgBean = list.get(0);
        studentMsgBean.setName("tang");
        msgBeanDao.update(studentMsgBean);
    }

    /**
     * 查询
     * 需要注意：offset需要和limit配合使用
     * list:所有实体类会直接加载到内存中
     * listLazy:当你需要使用时，才会加载，会自动缓存。使用完必须关闭
     * listLazyUncached:和listLazy一样，但是不会缓存，使用完也需要关闭
     * listIterator:通过迭代器遍历结果集，不会缓存，使用完需要关闭
     * unique:返回一个或者零个结果
     * uniqueOrThrow:返回非空的结果，否则会抛出异常
     * listLazy、listLazyUncached、listIterator这三个方法都使用了LazyList.class这个类。
     * 它持有了数据库游标的引用，这就是为什么要关闭的原因，当然，当你遍历完所有的结果集，它是会自动关闭的。如果没有遍历完，就得手动关闭了
     */
    @OnClick(R.id.tv_select)
    public void onTvSelectClicked() {
        List<StudentMsgBean> list = msgBeanDao.queryBuilder()
                //.offset(0)  // 偏移量，相当于SQL语句中的skip
                //.limit(2) //只获取结果集的前3个数据
                //.orderAsc(StudentMsgBeanDao.Properties.StudentNum)    // 通过StudentNum这个属性进行正序排序
                //.where(StudentMsgBeanDao.Properties.Name.eq("josan")) // 数据筛选，只获取Name = "josan"的数据
                .build()
                .list();
        String result = "结果为：\n";
        for (StudentMsgBean msgBean : list) {
            result += msgBean.getId() + "-";
            result += msgBean.getName() + "-";
            result += msgBean.getStudentNum() + "\n";
        }
        tvResult.setText(result);
    }

    /**
     * 多次查询
     * 通过QueryBuilder创建一个Query,Query对象可以在一次查询结束后重新使用
     * 相比较创建新的Query,这样更加高效如果查询参数没有改变，可再次调用list/unique方法；
     * 如果参数改变了，则必须调用
     */
    @OnClick(R.id.tv_multie_select)
    public void onViewClicked() {
        /*Query<StudentMsgBean> msgBeanQuery = msgBeanDao.queryBuilder().where(StudentMsgBeanDao.Properties.Name.eq("josan24")).build();
        List<StudentMsgBean> list = msgBeanQuery.list();
        String result = "结果为：\n";
        for (StudentMsgBean msgBean : list) {
            result += msgBean.getId() + "-";
            result += msgBean.getName() + "-";
            result += msgBean.getStudentNum() + "\n";
        }
        Log.e(TAG, "onViewClicked: list1:" + result);

        msgBeanQuery.setParameter(0, "josan25");
        List<StudentMsgBean> list2 = msgBeanQuery.list();
        String result2 = "";
        for (StudentMsgBean msgBean : list2) {
            result2 += msgBean.getId() + "-";
            result2 += msgBean.getName() + "-";
            result2 += msgBean.getStudentNum() + "\n";
        }
        Log.e(TAG, "onViewClicked: list2:" + result2);
*/
        List<StudentMsgBean> list3 = msgBeanDao.queryBuilder().list();
        String result3 = "";
        for (StudentMsgBean msgBean : list3) {
            result3 += msgBean.getId() + "-";
            result3 += msgBean.getName() + "-";
            result3 += "课程id：" + msgBean.getMScoreBean().getId() + "-";
            result3 += "英语成绩：" + msgBean.getMScoreBean().getEnglishScore() + "-";
            result3 += "数学成绩：" + msgBean.getMScoreBean().getMathScore() + "-";
            result3 += msgBean.getStudentNum() + "\n";
        }
        Log.e(TAG, "onViewClicked: list3:" + result3);



    }

    /**
     * 1：1的外键存储
     */
    @OnClick(R.id.tv_one_to_one)
    public void onClickOneToOne() {
        StudentMsgBean studentMsgBean = new StudentMsgBean();
        studentMsgBean.setName("josan1");
        studentMsgBean.setStudentNum("123");
        ScoreBean scoreBean = new ScoreBean();
        scoreBean.setEnglishScore("120");
        scoreBean.setMathScore("138");
        scoreBeanDao.insert(scoreBean);
        // 因为上面一行代码，scoreBean已经被插入到数据表中了，所以这时候scoreBean的主键Id是有值的
        // 所以就可以直接调用下面的代码，直接取出id，设置到StudentMsgBean到外键中
        studentMsgBean.setScoreId(scoreBean.getId());
        studentMsgBean.setMScoreBean(scoreBean);
        msgBeanDao.insert(studentMsgBean);
    }
}
